#include "Frustum.h"
#include "OBB.h"
#include "AABB.h"
Frustum::Frustum()
{
}

Frustum::Frustum( D3DXMATRIX projection )
{
	FromProjectionMatrix(projection);
}


void Frustum::FromProjectionMatrix(D3DXMATRIX matrix)
{
	//left plane
	planes[0].a = matrix(0,3) + matrix(0,0);
	planes[0].b = matrix(1,3) + matrix(1,0);
	planes[0].c = matrix(2,3) + matrix(2,0);
	planes[0].d = matrix(3,3) + matrix(3,0);

	//right plane
	planes[1].a = matrix(0,3) - matrix(0,0);
	planes[1].b = matrix(1,3) - matrix(1,0);
	planes[1].c = matrix(2,3) - matrix(2,0);
	planes[1].d = matrix(3,3) - matrix(3,0);

	//bottom plane	
	planes[2].a = matrix(0,3) + matrix(0,1);
	planes[2].b = matrix(1,3) + matrix(1,1);
	planes[2].c = matrix(2,3) + matrix(2,1);
	planes[2].d = matrix(3,3) + matrix(3,1);
	//top plane	  
	planes[3].a = matrix(0,3) - matrix(0,1);
	planes[3].b = matrix(1,3) - matrix(1,1);
	planes[3].c = matrix(2,3) - matrix(2,1);
	planes[3].d = matrix(3,3) - matrix(3,1);
	// near plane 		
	planes[4].a = matrix(0,2);
	planes[4].b = matrix(1,2);
	planes[4].c = matrix(2,2);
	planes[4].d = matrix(3,2);
	//far plane	  		
	planes[5].a = matrix(0,3) - matrix(0,2);
	planes[5].b = matrix(1,3) - matrix(1,2);
	planes[5].c = matrix(2,3) - matrix(2,2);
	planes[5].d = matrix(3,3) - matrix(3,2);

	for(int i = 0; i < 6; ++i )
		D3DXPlaneNormalize(&planes[i], &planes[i]);
}

/*
 * if all vertices is on behind of some clip plane,
 * function return false
*/
bool Frustum::CheckBox( OBB *box )
{
	const size_t vertexCount = 8; // the 8 vertex in the box
	const size_t planesCount = 6; // the 6 planes in the frustum

	D3DXVECTOR3 *vertices = box->GetVertices();
	int checked = 0;

	for( size_t i = 0; i < planesCount; ++i )
	{
		for( size_t j = 0; j < vertexCount; ++j )
		{
			//or D3DXPlaneDotCoord..
			float res = planes[i].a * vertices[j].x + planes[i].b * vertices[j].y + planes[i].c * vertices[j].z + planes[i].d;
			res > 0 ? ++checked : --checked;
		}

		if( checked == 8 ) // if all equation for box (8 vertices) > 0
			return false;
	}
	return true;
}